//
//  XSTabBarController.swift
//  XS微博
//
//  Created by 王小帅 on 2016/11/6.
//  Copyright © 2016年 王小帅. All rights reserved.
//

import UIKit

class XSMainController: UITabBarController {

    /// *** 这里注意如果设置私有属性 最新版的swift 不支持同文件(viewDidLoad)的访问，只能在同一个方法里才能访问  ***
    // 懒加载一个发送微博的按钮
    lazy var composeButton:UIButton = UIButton()
    // 定时检查未读消息
    fileprivate var timer:Timer?

    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        /// 设置tababr的自控制器
        setUpChilds()
        // 设置中间发微博的按钮
        setComponeBtn()
        // 定时获取未读微博数量
        setUpTimer()
        
        // 设置欢迎和新特性界面
        setupNFSAndWlViews()
        
        
        // 设置tabbarcontroller代理
        delegate = self
        
        // 注册用户登录通知,注意要销毁
        NotificationCenter.default.addObserver(self, selector: #selector(userLogin), name: NSNotification.Name(rawValue: XSUserLoginNotifitation), object: nil)
        
    }
    
    // 注意： 定义了timer必须释放
    deinit {
        timer?.invalidate()
        
        NotificationCenter.default.removeObserver(self)
    }
}


// MARK: - 接收用户登录的通知
extension XSMainController {

    // 用户登录
    func userLogin() {
        let vc = XSOAuthViewController()
        // 给弹出的界面一个返回按钮
        let nav = XSNavigationController(rootViewController: vc)
        
        // 弹出
        present(nav, animated: true, completion: nil)
    }

}

/// MARK: - 关于定时器的操作
extension XSMainController{
    
    // 定义10秒获取未读信息
    func setUpTimer() {
        // 如果非登录状态 不能查询服务器。注意：分类里职能定义方法。其他的都无法取到
        if XSNetworkTools.shared.userAccess.access_token == nil {
            return
        }

        // 设置定时器
        timer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(unReadStatusCount), userInfo: nil, repeats: true)
    }
    
    /// 获取未读微博数量
    func unReadStatusCount(){
        
        XSNetworkTools.shared.unReadCount { (count) in
            
            print("未读微博数量  ： \(count)")
            // 设置tabbar上的小圆点这里注意如果为0 要设置为nil 否则会有很丑的大圆点
            ((self.tabBar.items?[0])! as UITabBarItem).badgeValue = count > 0 ? "\(count)" : nil
            // 设置app的提醒消息显示(这里如果是0条 自动不显示)
            // 这样ios8 以后要app去请求用户的允许才能显示 在程序入口处 去做请求
            UIApplication.shared.applicationIconBadgeNumber = count
            
        }
    }
    

}


// MARK: - 设置点击baritem 会到顶部并刷新
// 利用 tbabarcontroller的代理来完成
extension XSMainController: UITabBarControllerDelegate {
    
    // 利用tabbar的 将要显示自控制器的方法来设置
    // 同时还可以将中间的写微博的安努的操作盲区方法给省略。 如果将要显示的控制器不是首页消息等返回false 不显示
    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        
        // 发现如果是首页／消息／发现／我 等都是切换到xsnavitationcontroller  所以根据这个可以判断点击到是不是发微博按钮
        // 如果是发微博按钮久不切换，这样就避免的误触区
        let flag = viewController.isMember(of: XSNavigationController.self)
        
        // 判断当前所处的控制器，如果是切换回首页那么不做操作
        // 如果当前已经在首页了，那么在点击首页的item  就要回到tableview的顶部并且刷新数据
        let currentIndex = selectedIndex
        let willShowIndex = tabBarController.childViewControllers.index(of: viewController)
        // 点击的是当前页(首页)
        if currentIndex == willShowIndex && currentIndex == 0 {
        
            // 获取首页控制器
            let nav = viewController as! XSNavigationController
            let home = nav.childViewControllers[0] as! XSHomeViewController
            
            // 如果症状刷新那就不刷新了
//            if home.refresh?.isRefreshing == false {
            // 手动刷新
            home.beginRefresh()
//        }
        
            // 清空tabbaritem的提示数字以及appicon的提示数字
            home.tabBarItem.badgeValue = nil
            UIApplication.shared.applicationIconBadgeNumber = 0
            
        }
        
        return flag
    }
    
    
}


// MARK: - 设置新特性和欢迎界面
extension XSMainController{

    func setupNFSAndWlViews() {
        // 如果用户没登陆那么啥事也不干
        if !XSNetworkTools.shared.userLogon {
            return
        }
        
        // 设置状态栏
        IsHidedStatusBar = true
        // 判断是否为新版本觉得展示的欢迎界面还是新特性
        let v = isNewVersion ? XSNewFeatureView.newFeatureView() : XSWelcomeView.welcomeView()
       v.frame = view.bounds
       view.addSubview(v)
        
    }
    
    
    
    // 获取版本号判断是否应该显示新特性
    var isNewVersion:Bool {
    
        // 当前版本信息
        let currentVer = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String)

        // 用户偏好里的版本信息
        let keyStr = "version"
        let version = UserDefaults.standard.string(forKey: keyStr) ?? " "
        
        // 更新偏好设置里的版本信息
        UserDefaults.standard.set(currentVer, forKey: keyStr)
        
        return currentVer != version
    }
    
    /// 发微博按钮点击
    @objc func compseButtonClick(){
        // 微博类型界面
        let v = XSCompseTypeView.composeTypeView()

        v.show { [weak v] (clsName) in
            
            // 判断是否有控制器
            guard let clsName = clsName,
            let vc = NSClassFromString(Bundle.main.namespace + "." + clsName) as? UIViewController.Type
                else {
                
                // 注意 清楚循环引用v
                v?.removeFromSuperview()
                return
            }
            
            // model出界面
            let view = vc.init()
            let nav = UINavigationController(rootViewController: view)
            
            self.present(nav, animated: true, completion: {
                
                // 删除微博类型选择节目
                v?.removeFromSuperview()
            })
        }
    }
}



/// extension 类似OC中的分类，同样的不能定义属性只能定义方法
/// extension 可以将功能相似的代码分块
/// 下面的代码用来给主控制器初始化
/// *** 这里我将extension 直接变为来私有 而不是将每个方法前加 private  ***
/// *** 因为当前的swift版本中 当我在方法前加private的时候，viewDidLoad中无法调用  ***
extension XSMainController {
    
    /// 设置中间发微博的加号按钮
    func setComponeBtn() {
        
        // 设置按钮的前景和背景图片
        let imgNormal = UIImage(named: "tabbar_compose_icon_add")
        let imgHightlightred = UIImage(named: "tabbar_compose_icon_add_highlighted")
        let imgBackNormal = UIImage(named: "tabbar_compose_button")
        let imgBackHightlighted = UIImage(named: "tabbar_compose_button_highlighted")
        // 分别设置图片等状态
        composeButton.setImage(imgNormal, for: .normal)
        composeButton.setImage(imgHightlightred, for: .highlighted)
        composeButton.setBackgroundImage(imgBackNormal, for: .normal)
        composeButton.setBackgroundImage(imgBackHightlighted, for: .highlighted)
        
        // 将按钮加到view
        tabBar.addSubview(composeButton)
        
        // 计算位置
        let tabbarW = tabBar.bounds.width
        // 空间个数
        let count = CGFloat(childViewControllers.count)
        // 每个按钮的宽度
        let btnW = tabbarW / count // ***这里是解决容错区的，之后利用tabbarcontroller的代理方法解决了***
        // 剧中添加按钮
        // *** 注意：这样虽然把按钮加入中间但是，tabbar上的每个按钮之间会有空隙（容错区）所以避免误触，要将加号按钮做大 ***
        composeButton.frame = tabBar.bounds.insetBy(dx: 2 * btnW, dy: 0)
        
        // 点击
        composeButton.addTarget(self, action: #selector(compseButtonClick), for: .touchUpInside)
        
    }
    
    /// 设置tababr的自控制器
    func setUpChilds(){
        
        // 从bundle中取出json文件设置界面
        guard let path = Bundle.main.path(forResource: "demo.json", ofType: nil),
            let data = NSData(contentsOfFile: path),
            let sourceArr = try? JSONSerialization.jsonObject(with: data as Data, options: [])  as? [[String: AnyObject]]
         else{
        
            return
        }
        
        // 装有子试图控制的数组
        var arrayM = [UIViewController]()
        // 循环创建子视图 加入到数组中
        for dict in sourceArr!{
            let vc = controllers(dict: dict)
            arrayM.append(vc)
        }
        // 赋值子视图控制器
        viewControllers = arrayM
    }
    
    
    /// 根据字典来获取子控制器
    ///
    /// - Parameter dict: 存放自控制器的字典 ["clsName": " ","title": " ","imgName": " "]
    /// - Returns: 自控制器
    func controllers(dict: [String: AnyObject]) -> UIViewController{
        
        // 从字典里取值是可选的这里用守卫来避免nil
        // 最新版本的swift guard let [] ,每一个属性必须都有let ，上一版本不用这样
        guard let clsName = dict["clsName"] as? String,
              let title = dict["title"] as? String,
              let imgName = dict["imgName"] as? String,
              let cls = NSClassFromString(Bundle.main.namespace + "." + clsName) as? XSBaseViewController.Type,
            let vistorInfoDict = dict["vistorInfo"] as? [String: String]
            else {
                
                // 如果字典取值失败 那么返回一个空的自控制器
                // 剧透下： 因为中间会有一个发微博的加号按钮所以要用一个空的控制器来占位置
                return UIViewController()
        }
        
        // 通过了守卫，说明所以属性都已经取值成功，那么运用反射机制来获取自控制器
        // *** 既然cls 依然为可选的  那么直接也一起放到守卫中
//        let cls = NSClassFromString(clsName) as? UIViewController.Type
        
        // 获取控制器
        let vc = cls.init()
        // 设置属性
        vc.title = title
        // 图片normal
        vc.tabBarItem.image = UIImage(named: "tabbar_" + imgName)
        // hightlighted  注意渲染model 选中不使用tint color  用图片本身
        vc.tabBarItem.selectedImage = UIImage(named: "tabbar_" + imgName + "_highlighted")?.withRenderingMode(.alwaysOriginal)
        // 设置tabbar的字体颜色和大小
        vc.tabBarItem.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.orange], for: .highlighted)
        // 设置大小的话 只能是normal 状态  高亮状态的字体大小是不能设置的.系统默认字体大小 12 号
        vc.tabBarItem.setTitleTextAttributes([NSFontAttributeName: UIFont.systemFont(ofSize: 13)], for: .normal)
        
        // 设置vc的 访客信息字典
        vc.vistorInfo = vistorInfoDict
        
        // 将控制器用导航控制器包装
        let nav = XSNavigationController(rootViewController: vc)
        // 返回导航控制器  这里是面向对象的多态
        return nav
    }
}
